package pers.dawnyang.config.shiro;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.util.WebUtils;
import com.alibaba.fastjson.JSONObject;
import pers.dawnyang.common.enums.ResultEnum;
import pers.dawnyang.common.util.ResultUtil;

/**
 * 自定义未登录拦截，返回json，code408
 * 
 * @author dawn yang
 * @date 2021/04/13
 */
public class UserAuthFilter extends AccessControlFilter {

  @Override
  protected boolean isAccessAllowed(ServletRequest request, ServletResponse response,
      Object mappedValue) {
    if (isLoginRequest(request, response)) {
      return true;
    } else {
      Subject subject = getSubject(request, response);
      return subject.getPrincipal() != null
          && (subject.isRemembered() || subject.isAuthenticated());
    }
  }

  @Override
  protected boolean onAccessDenied(ServletRequest request, ServletResponse response)
      throws Exception {
    HttpServletRequest httpRequest = WebUtils.toHttp(request);
    HttpServletResponse httpResponse = WebUtils.toHttp(response);
    if (httpRequest.getHeader("X-Requested-With") != null
        && "XMLHttpRequest".equalsIgnoreCase(httpRequest.getHeader("X-Requested-With"))) {
      // httpResponse.sendError(ResultEnum.LOGIN_TIMEOUT.getCode());
      // 这里是个坑，如果不设置的接受的访问源，那么前端都会报跨域错误，因为这里还没到corsConfig里面
      httpResponse.setHeader("Access-Control-Allow-Origin",
          ((HttpServletRequest) request).getHeader("Origin"));
      httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
      httpResponse.setCharacterEncoding("UTF-8");
      httpResponse.setContentType("application/json");
      httpResponse.getWriter()
          .write(JSONObject.toJSON(ResultUtil.error(ResultEnum.ERROR_SESSION_EXPIRES)).toString());
      return false;
    } else {
      redirectToLogin(request, response);
      return false;
    }
  }
}
